home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / dwarf_global.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  6.7 KB  |  269 lines

  1. #include <stdio.h>
  2. #include "dwarf_incl.h"
  3. #include "dwarf_global.h"
  4.  
  5. int
  6. dwarf_get_globals (
  7.     Dwarf_Debug        dbg,
  8.     Dwarf_Global    **globals,
  9.     Dwarf_Signed       *return_count,
  10.     Dwarf_Error        *error
  11. )
  12. {
  13.     /* Sweeps the complete .debug_pubnames section. */
  14.     Dwarf_Small            *pubnames_ptr;
  15.  
  16.     Dwarf_Unsigned        length;
  17.  
  18.     /* 
  19.         Points to the context for the current set of global names,
  20.         and contains information to identify the compilation-unit
  21.         that the set refers to.
  22.     */
  23.     Dwarf_Global_Context    pubnames_context;
  24.  
  25.         /* Version number for the current set of pubnames. */
  26.     Dwarf_Half            version;
  27.  
  28.     /* 
  29.         Offset from the start of compilation-unit 
  30.         for the current global.
  31.     */
  32.     Dwarf_Off            cu_offset;
  33.  
  34.     /* Counts the number of globals read. */
  35.     Dwarf_Unsigned        global_count = 0;
  36.  
  37.     /* Points to the current global read. */
  38.     Dwarf_Global        global;
  39.  
  40.     /* 
  41.         Used to chain the Dwarf_Global_s structs for creating
  42.         contiguous list of pointers to the structs.
  43.     */
  44.     Dwarf_Chain            curr_chain, prev_chain, head_chain = NULL;
  45.  
  46.     /* Points to contiguous block of Dwarf_Global's to be returned. */
  47.     Dwarf_Global        *ret_globals;
  48.  
  49.     /* Temporary counter. */
  50.     Dwarf_Unsigned        i;
  51.  
  52.     /* ***** BEGIN CODE ***** */
  53.  
  54.  
  55.     if (dbg == NULL) {
  56.     _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 
  57.     return(DW_DLV_ERROR);
  58.     }
  59.  
  60.     if (dbg->de_debug_pubnames == NULL) {
  61.     return(DW_DLV_NO_ENTRY);
  62.     }
  63.  
  64.     pubnames_ptr = dbg->de_debug_pubnames;
  65.     do {
  66.     pubnames_context = (Dwarf_Global_Context)
  67.         _dwarf_get_alloc(dbg, DW_DLA_GLOBAL_CONTEXT, 1);
  68.     if (pubnames_context == NULL) {
  69.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  70.         return(DW_DLV_ERROR);
  71.     }
  72.  
  73.     READ_UNALIGNED(length, pubnames_ptr, dbg->de_length_size);
  74.     pubnames_ptr += dbg->de_length_size;
  75.     pubnames_context->pu_length = length;
  76.  
  77.  
  78.     READ_UNALIGNED(version, pubnames_ptr, sizeof(Dwarf_Half));
  79.     pubnames_ptr += sizeof(Dwarf_Half);
  80.     if (version != CURRENT_VERSION_STAMP) {
  81.         _dwarf_error(dbg, error, DW_DLE_PUBNAMES_VERSION_ERROR);
  82.         return(DW_DLV_ERROR);
  83.     }
  84.  
  85.     READ_UNALIGNED(pubnames_context->pu_info_offset, pubnames_ptr, 
  86.         dbg->de_length_size);
  87.     pubnames_ptr += dbg->de_length_size;
  88.     
  89.         /* 
  90.         Add the length of the cu_header to point to the
  91.         DW_TAG_compile_unit die.
  92.         */
  93.     pubnames_context->pu_info_offset +=
  94.         dbg->de_length_size +    /* Size of cu length field. */
  95.         sizeof(Dwarf_Half) +    /* Size of version stamp field. */
  96.         dbg->de_length_size +    /* Size of abbrev offset field. */
  97.         sizeof(Dwarf_Small);    /* Size of address size field. */
  98.  
  99.     READ_UNALIGNED(pubnames_context->pu_info_length, pubnames_ptr, 
  100.         dbg->de_length_size);
  101.     pubnames_ptr += dbg->de_length_size;
  102.  
  103.     if (pubnames_ptr > dbg->de_debug_pubnames +
  104.         dbg->de_debug_pubnames_size) {
  105.         _dwarf_error(dbg, error, DW_DLE_PUBNAMES_LENGTH_BAD);
  106.         return(DW_DLV_ERROR);
  107.     }
  108.  
  109.     READ_UNALIGNED(cu_offset, pubnames_ptr, dbg->de_length_size);
  110.     pubnames_ptr += dbg->de_length_size;
  111.  
  112.     while (cu_offset != 0) {
  113.  
  114.             global = (Dwarf_Global)_dwarf_get_alloc(dbg, DW_DLA_GLOBAL, 1);
  115.         if (global == NULL) {
  116.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  117.         return(DW_DLV_ERROR);
  118.         }
  119.         global_count++;
  120.  
  121.         global->gl_context = pubnames_context;
  122.  
  123.         /* Subtract length of CU header to adjust offsets. */
  124.             global->gl_cu_offset = cu_offset -
  125.         dbg->de_length_size -    /* Size of CU length field. */
  126.         sizeof(Dwarf_Half) -    /* Size of version stamp field. */
  127.         dbg->de_length_size -    /* Size of abbrev offset field. */
  128.         sizeof(Dwarf_Small);    /* Size of address size field. */
  129.  
  130.         global->gl_name = pubnames_ptr;
  131.         pubnames_ptr = pubnames_ptr + strlen(pubnames_ptr) + 1;
  132.  
  133.         READ_UNALIGNED(cu_offset, pubnames_ptr, dbg->de_length_size);
  134.         pubnames_ptr += dbg->de_length_size;
  135.  
  136.         if (pubnames_ptr > dbg->de_debug_pubnames + 
  137.         dbg->de_debug_pubnames_size) {
  138.         _dwarf_error(dbg, error, DW_DLE_PUBNAMES_LENGTH_BAD);
  139.         return(DW_DLV_ERROR);
  140.         }
  141.  
  142.         curr_chain = (Dwarf_Chain)_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  143.         if (curr_chain == NULL) {
  144.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  145.         return(DW_DLV_ERROR);
  146.         }
  147.  
  148.         /* Put current global on singly_linked list. */
  149.         curr_chain->ch_item = (Dwarf_Global)global;
  150.         if (head_chain == NULL)
  151.         head_chain = prev_chain = curr_chain;
  152.         else {
  153.         prev_chain->ch_next = curr_chain;
  154.         prev_chain = curr_chain;
  155.         }
  156.     }
  157.  
  158.     } while 
  159.     (pubnames_ptr < dbg->de_debug_pubnames + dbg->de_debug_pubnames_size);
  160.     
  161.     /* Points to contiguous block of Dwarf_Global's. */
  162.     ret_globals = (Dwarf_Global *)
  163.     _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
  164.     if (ret_globals == NULL) 
  165.     {_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return(DW_DLV_ERROR);}
  166.  
  167.     /* 
  168.         Store pointers to Dwarf_Global_s structs in
  169.         contiguous block, and deallocate the chain.
  170.     */
  171.     curr_chain = head_chain;
  172.     for (i = 0; i < global_count; i++) {
  173.     *(ret_globals + i) = curr_chain->ch_item;
  174.     prev_chain = curr_chain;
  175.     curr_chain = curr_chain->ch_next;
  176.     dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
  177.     }
  178.  
  179.     *globals = ret_globals;
  180.     *return_count = (global_count);
  181.     return DW_DLV_OK;
  182. }
  183.  
  184.  
  185. int
  186. dwarf_globname (
  187.     Dwarf_Global    glob,
  188.     char **             ret_name,
  189.     Dwarf_Error        *error
  190. )
  191. {
  192.     if (glob == NULL)
  193.     {_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return(DW_DLV_ERROR);}
  194.  
  195.     *ret_name = (glob->gl_name);
  196.     return DW_DLV_OK;
  197. }
  198.  
  199.  
  200. dwarf_global_die_offset (
  201.     Dwarf_Global    global,
  202.     Dwarf_Off          *ret_off,
  203.     Dwarf_Error        *error
  204. )
  205. {
  206.     if (global == NULL) {
  207.     _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 
  208.     return(DW_DLV_ERROR);
  209.     }
  210.  
  211.     if (global->gl_context == NULL) {
  212.     _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
  213.     return(DW_DLV_ERROR);
  214.     }
  215.  
  216.     *ret_off = (global->gl_cu_offset + global->gl_context->pu_info_offset);
  217.     return DW_DLV_OK;
  218. }
  219.  
  220.  
  221. int
  222. dwarf_global_cu_offset (
  223.     Dwarf_Global    global,
  224.     Dwarf_Off          *ret_off,
  225.     Dwarf_Error        *error
  226. )
  227. {
  228.     if (global == NULL) {
  229.     _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 
  230.     return(DW_DLV_ERROR);
  231.     }
  232.  
  233.     if (global->gl_context == NULL) {
  234.     _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
  235.     return(DW_DLV_ERROR);
  236.     }
  237.  
  238.     *ret_off = (global->gl_context->pu_info_offset);
  239.     return DW_DLV_OK;
  240. }
  241.  
  242. int
  243. dwarf_global_name_offsets (
  244.     Dwarf_Global    global,
  245.     char               **ret_name,
  246.     Dwarf_Off        *die_offset,
  247.     Dwarf_Off        *cu_offset,
  248.     Dwarf_Error        *error
  249. )
  250. {
  251.     if (global == NULL)
  252.     {_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return(DW_DLV_ERROR);}
  253.  
  254.     if (global->gl_context == NULL) 
  255.     {_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 
  256.     return(DW_DLV_ERROR);}
  257.  
  258.     if (die_offset != NULL)
  259.     *die_offset = global->gl_cu_offset + 
  260.         global->gl_context->pu_info_offset;
  261.  
  262.     if (cu_offset != NULL)
  263.     *cu_offset = global->gl_context->pu_info_offset;
  264.  
  265.     *ret_name = global->gl_name;
  266.     return DW_DLV_OK;
  267. }
  268.  
  269.